package com.fulihui.information.biz.content.impl;


import com.alibaba.fastjson.JSON;
import com.fulihui.information.biz.content.ContentBizManager;
import com.fulihui.information.biz.content.SpiderDataProcessBiz;
import com.fulihui.information.biz.conv.ContentConv;
import com.fulihui.information.common.config.AppConst;
import com.fulihui.information.core.oss.Aliyun;
import com.fulihui.information.core.oss.EImgFileHeaderType;
import com.fulihui.information.core.oss.ImgKit;
import com.fulihui.information.core.oss.ToBeUploadData;
import com.fulihui.information.dal.dataobj.InfoCategory;
import com.fulihui.information.dal.dataobj.InfoContent;
import com.fulihui.information.dal.dataobj.InfoContentExample;
import com.fulihui.information.dal.dataobj.InfoSource;
import com.fulihui.information.dal.mapper.InfoCategoryMapper;
import com.fulihui.information.dal.mapper.InfoContentMapper;
import com.fulihui.information.dal.mapper.InfoSourceMapper;
import com.fulihui.information.dto.ContentJson;
import com.fulihui.information.dto.ContentListItemDTO;
import com.fulihui.information.dto.ListImgJson;
import com.fulihui.information.enums.*;
import com.fulihui.information.request.SpiderDataUploadRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.common.utils.ConcurrentHashSet;

import org.near.servicesupport.error.Errors;
import org.near.servicesupport.error.InvokeServiceException;
import org.near.toolkit.common.DateUtils;
import org.near.toolkit.common.EnumUtil;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import javax.annotation.PostConstruct;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.text.ParseException;
import java.util.*;

import static org.apache.commons.lang3.StringUtils.isNotEmpty;
import static org.springframework.util.CollectionUtils.isEmpty;

/**
 * @author LeeSon on 2016/12/26 0026.
 */
@Component
@Slf4j
public class SpiderDataProcessBizImpl implements SpiderDataProcessBiz {
    @Autowired
    private InfoCategoryMapper infoCategoryMapper;
    @Autowired
    private InfoSourceMapper infoSourceMapper;
    @Autowired
    private InfoContentMapper infoContentMapper;
    @Autowired
    private Aliyun aliyun;
    @Autowired
    private AppConst appConst;
    @Autowired
    private ContentBizManager contentBizManager;

    @PostConstruct
    public void init() {
        ImageIO.setUseCache(false);
    }

    @Override
    @Transactional
    public void process(SpiderDataUploadRequest request) {
        log.info("PROCESS " + request.getTrackNo());
        Date now = new Date();

        //等待上传的图片资源信息
        Set<ToBeUploadData> toBeUploadDataSet = new ConcurrentHashSet<>();
        try {
            //上传记录信息
            InfoContent content = new InfoContent();
            String contentId = String.valueOf(UUID.randomUUID());
            content.setId(contentId);
            content.setTopStatus(EYesOrNo.NO.getCode());
            content.setTitle(request.getTitle());
            try {
                content.setSubmitTime(DateUtils.parseNewFormat(request.getSourceTime()));
            } catch (ParseException | NullPointerException e) {
                content.setSubmitTime(now);
            }
            content.setSrcRead(request.getRead_());
            content.setSrcShared(request.getShared_());
            content.setSrcSource(request.getSource_());
            content.setListComment(request.getListComment());
            content.setSrcHref(request.getSrcHref());
            content.setStatus(EContentStatus.UNCHECK.getCode());
            content.setOperator("SYSTEM");

            content.setGmtCreate(now);
            content.setGmtModified(now);
            // 使用提交时间的秒数作为默认分数
            content.setScore(content.getSubmitTime().getTime() / 1000);

            //类目信息
            String catagoryCode = request.getCategoryCode();
            InfoCategory category = infoCategoryMapper.selectByPrimaryKey(catagoryCode);
            Assert.notNull(category);
            content.setCategoryCode(catagoryCode);

            //渠道信息
            String sourceCode = request.getSourceCode();
            InfoSource source = infoSourceMapper.selectByPrimaryKey(sourceCode);
            Assert.notNull(source);
            content.setSourceCode(sourceCode);

            //设置免审
            if (source.getCheck().equals(ESourceStatus.UC.getCode())) {
                content.setStatus(EContentStatus.CHECK.getCode());
            }

            //渠道数据去重
            String unioCode = request.getUnionCode();
            if (isNotEmpty(unioCode)) {
                InfoContentExample contentExample = new InfoContentExample();
                InfoContentExample.Criteria criteria = contentExample.createCriteria();
                criteria.andSourceCodeEqualTo(sourceCode);
                criteria.andUnionCodeEqualTo(unioCode);
                List<InfoContent> infoContents = infoContentMapper.selectByExample(contentExample);
                if (!isEmpty(infoContents)) {
                    log.info("重复 " + request.getTrackNo());
                    return;
                }
                content.setUnionCode(unioCode);
            }

            //列表图片信息
            String listImgs = request.getListImgsJson();
            if (isNotEmpty(listImgs)) {
                List<ListImgJson> listImgJsonList = JSON.parseArray(listImgs, ListImgJson.class);
                for (ListImgJson l : listImgJsonList) {
                    //图片名称
                    String imageKey = String.valueOf(UUID.randomUUID());
                    //下载图片
                    String filePath = ImgKit.downloadImg(l.getImg(), appConst.getImgTmpDir(),
                            imageKey);
                    Assert.notNull(filePath);
                    //等待上传的图片数据
                    ToBeUploadData uploadData = new ToBeUploadData();
                    uploadData.setType(EImgFileHeaderType.PNG);
                    uploadData.setFileName(imageKey + "." + uploadData.getType().getDesc());
                    uploadData.setFilePath(filePath);
                    uploadData
                            .setOssUrl("http://" + appConst.getOssBucket() + "."
                                    + appConst.getOssEndpoint() + "/" + uploadData.getFileName());
                    toBeUploadDataSet.add(uploadData);
                    //设置图片宽高
                    BufferedImage bufferedImage = ImageIO.read(new File(filePath));
                    l.setWidth(bufferedImage.getWidth());
                    l.setHeight(bufferedImage.getHeight());
                    l.setImg(uploadData.getOssUrl());
                }
                content.setListImgs(JSON.toJSONString(listImgJsonList));
            }

            //链接类型
            String linkType = request.getLinkType();
            Assert.isTrue(EnumUtil.inEnum(linkType, ELinkType.class));
            content.setLinkType(linkType);

            //内链类型才需要处理详情页面
            if (linkType.equalsIgnoreCase(ELinkType.INSIDE.getCode())) {
                //详情页面信息
                String contents = request.getContentJson();
                List<ContentJson> contentJsonList = JSON.parseArray(contents, ContentJson.class);

                int index = 1;
                for (ContentJson c : contentJsonList) {
                    Assert.isTrue(EnumUtil.inEnum(c.getType(), EContentType.class));

                    //趣味图片需要做特殊处理
                    if (c.getType().equals(EContentType.GIF.getCode())
                            && catagoryCode.equalsIgnoreCase("YOUKANTOU_IMAGES_FUNNY")) {
                        //图片名称
                        String imageKey = String.valueOf(UUID.randomUUID());
                        //下载图片
                        String filePath = ImgKit.downloadImg(c.getData(), appConst.getImgTmpDir(),
                                imageKey);
                        Assert.notNull(filePath);
                        //等待上传的原图
                        ToBeUploadData uploadData = new ToBeUploadData();
                        uploadData.setType(EImgFileHeaderType.GIF);
                        uploadData.setFileName(imageKey + "." + uploadData.getType().getDesc());
                        uploadData.setFilePath(filePath);
                        uploadData.setOssUrl(
                                "http://" + appConst.getOssBucket() + "." + appConst.getOssEndpoint()
                                        + "/" + uploadData.getFileName());
                        toBeUploadDataSet.add(uploadData);
                        //设置图片宽高
                        BufferedImage bufferedImage = ImageIO.read(new File(filePath));
                        c.setWidth(bufferedImage.getWidth());
                        c.setHeight(bufferedImage.getHeight());
                        c.setData(uploadData.getOssUrl());

                        //获取第一帧
                        String tag = "_1";
                        boolean gifFirst = ImgKit.gifFirst(filePath, tag);
                        Assert.notNull(gifFirst);
                        //等待上传的第一帧
                        ToBeUploadData uploadData1 = new ToBeUploadData();
                        uploadData1.setType(EImgFileHeaderType.PNG);
                        uploadData1
                                .setFileName(imageKey + tag + "." + uploadData1.getType().getDesc());
                        uploadData1.setFilePath(filePath + tag);
                        uploadData1.setOssUrl(
                                "http://" + appConst.getOssBucket() + "." + appConst.getOssEndpoint()
                                        + "/" + uploadData1.getFileName());
                        toBeUploadDataSet.add(uploadData1);
                        //设置列表图片和宽高
                        BufferedImage bufferedImage1 = ImageIO.read(new File(filePath));
                        List<ListImgJson> listImgJsonList = new LinkedList<>();
                        listImgJsonList.add(new ListImgJson(uploadData1.getOssUrl(),
                                bufferedImage1.getWidth(), bufferedImage1.getHeight()));
                        content.setListImgs(JSON.toJSONString(listImgJsonList));
                    } else if (c.getType().equals(EContentType.IMG.getCode())) {
                        //图片名称
                        String imageKey = String.valueOf(UUID.randomUUID());
                        //下载图片
                        String filePath = ImgKit.downloadImg(c.getData(), appConst.getImgTmpDir(),
                                imageKey);
                        Assert.notNull(filePath);
                        //等待上传的原图
                        ToBeUploadData uploadData = new ToBeUploadData();
                        uploadData.setType(EImgFileHeaderType.PNG);
                        uploadData.setFileName(imageKey + "." + uploadData.getType().getDesc());
                        uploadData.setFilePath(filePath);
                        uploadData.setOssUrl(
                                "http://" + appConst.getOssBucket() + "." + appConst.getOssEndpoint()
                                        + "/" + uploadData.getFileName());
                        toBeUploadDataSet.add(uploadData);
                        //设置图片宽高
                        BufferedImage bufferedImage = ImageIO.read(new File(filePath));
                        c.setWidth(bufferedImage.getWidth());
                        c.setHeight(bufferedImage.getHeight());
                        c.setData(uploadData.getOssUrl());

                        //美女图库需要特殊处理 第一张图片设置为列表图片
                        if (index == 1 && catagoryCode.equalsIgnoreCase("YOUKANTOU_IMAGES_ESSAY")) {
                            List<ListImgJson> listImgJsonList = new LinkedList<>();
                            listImgJsonList.add(new ListImgJson(uploadData.getOssUrl(),
                                    bufferedImage.getWidth(), bufferedImage.getHeight()));
                            content.setListImgs(JSON.toJSONString(listImgJsonList));
                        }
                        index++;
                    }
                }
                content.setContents(JSON.toJSONString(contentJsonList));
            }

            int insertContent = infoContentMapper.insertSelective(content);
            if (insertContent == 0) {
                throw new InvokeServiceException(Errors.Commons.SYSTEM_ERROR);
            }

            // 如果存入数据是审核状态，将内容同步到Redis中
            if (content.getStatus().equals(EContentStatus.CHECK.getCode())) {
                log.info("将数据同步存入Redis中");
                ContentListItemDTO item = ContentConv.toDTO(content, ContentListItemDTO.class);
                contentBizManager.saveItemsToRedis(Collections.singletonList(item));
            }

            for (ToBeUploadData t : toBeUploadDataSet) {
                aliyun.upload(t.getFileName(), t.getType().getDesc(), t.getFilePath());
                log.info("OSS SUCCESS: " + t.getFilePath());
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new InvokeServiceException(Errors.Commons.SYSTEM_ERROR);
        }
    }
}